package application;

import application.support.de.svenjacobs.loremipsum.LoremIpsum;
import dao.inte.*;
import domain.MyConfiguration;
import domain.Template;
import domain.User;
import domain.cms.CmsPage;
import domain.shop.Category;
import domain.shop.DeliveryMethod;
import domain.shop.PayMethod;
import domain.shop.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import service.facade.admin.CmsAdminService;
import service.facade.admin.ShopAdminService;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

/**
 * This class create TestData after it has been activated.
 */

@Transactional
public class DataInitializer {
    private static Logger logger = Logger.getLogger(DataInitializer.class.getName());
    @Autowired(required = true)
    ShopAdminService shopAdminService;
    CmsAdminService cmsAdminService;
    @Autowired(required = true)
    CmsPageRepository cmsPageRepository;
    @Autowired(required = true)

    ConfigurationRepository configurationRepository;
    @Autowired(required = true)

    TemplateRepository templateRepository;
    private CategoryRepository categoryRepository;
    private ProductRepository productRepository;
    private DeliveryMethodRepository deliveryMethodRepository;
    private PayMethodRepository payMethodRepository;
    private UserRepository userRepository;
    LoremIpsum loremIpsum;
    User admin;

    public DataInitializer() {
    }

    @SuppressWarnings("unchecked")

    public void go() throws Exception {


        if (userRepository.findAll().size() != 0) {
            logger.info("zadnej init " + userRepository.findAll().size());

        } else {
            MySession session = new MySession();
            session.setId(Long.valueOf(1));
            cmsAdminService.setMySession(session);
            logger.info("INITUJI HODNOIY");
            MyConfiguration foo = new MyConfiguration();
            configurationRepository.save(foo);
            logger.info("INITUJI initValues");
            createDeliveryMethods();
            createPayMethods();
            createUsers();
            initTemplates();

            createCategoriesAndProducts();
            logger.info("INITUJI makeSection");
            makeSection();
        }

    }

    private void initTemplates() throws Exception {
        Template template = new Template("accountActivationMailTemplate", "vas ucet byl aktivovan");
        templateRepository.save(template);
        template = new Template("passwordResetRequestTemplate", "chtel nekdo nove heslo?\n" +
                "\n" +
                "link : ${passwordResetLink}/${key}");
        templateRepository.save(template);
        template = new Template("passwordResetTemplate", "novy heslo:: ff\n" +
                "\n" +
                "login  : $user.login\n" +
                "heslo : $password");
        templateRepository.save(template);
        template = new Template("orderMailTemplate", "Údaje zákazníka\n" +
                "----------------------------------------------------------------------------\n" +
                "Jméno:                           $user.firstName $user.lastName\n" +
                "Firma:                            $user.tradingName\n" +
                "IČO:                               $user.companyID\n" +
                "DIČ:                               $user.taxID\n" +
                "Adresa:                          $address.street\n" +
                "Město:                           $address.municipality\n" +
                "PSČ:                             $address.postcode\n" +
                "E-mail:                           $user.login\n" +
                "Telefon:                               $user.phone\n" +
                "Fax:                               $user.fax\n" +
                "Telefon (firemní):                               $user.phone\n" +
                "Fax (firemní):                               $user.phone\n" +
                "E-mail (firemní):                $user.companyEmail\n" +
                "\n" +
                "----------------------------------------------------------------------------\n" +
                "Datum potvrzení objednavky:  $order.date\n" +
                "Zákazníkovo označení:\n" +
                "Doprava: $order.deliveryMethod.name $order.deliveryMethod.price\n" +
                "Platba: $order.payMethod.name\n" +
                "Doručovací adresa: $order.deliveryAddress.street, $order.deliveryAddress.municipality,  $order.deliveryAddress.country\n" +
                "\n" +
                "\n" +
                "\n" +
                "#foreach( $item in $items)\n" +
                "    ${item.multiplicity}x ${item.price},- ${item.name}\n" +
                "\n" +
                "#end\n" +
                "\n" +
                "\n" +
                "Celková hodnota bez DPH v Kč:  ${price},-\n" +
                "Cena je včetně poplatků\n" +
                "\n" +
                "Děkujeme za Vaši objednávku.");
        templateRepository.save(template);
        template = new Template("registrationMailTemplate", "Ăšdaje zĂˇkaznĂ­ka\n" +
                "----------------------------------------------------------------------------\n" +
                "JmĂ©no:                           $user.firstName $user.lastName\n" +
                "Firma:                            $user.tradingName\n" +
                "IÄŚO:                               $user.companyID\n" +
                "DIÄŚ:                               $user.taxID\n" +
                "Adresa:                          $address.street\n" +
                "MÄ›sto:                           $address.municipality\n" +
                "PSÄŚ:                             $address.postcode\n" +
                "E-mail:                           $user.login\n" +
                "Telefon:                               $user.phone\n" +
                "Fax:                               $user.fax\n" +
                "Telefon (firemnĂ­):                               $user.phone\n" +
                "Fax (firemnĂ­):                               $user.phone\n" +
                "E-mail (firemnĂ­):                $user.companyEmail");
        templateRepository.save(template);
    }

    @Transactional
    private void createProducts(Category c1, Category c2, Category c3, Category c4, Category c5) throws Exception {
        Product p1 = new Product();
        p1.setContent(loremIpsum.getWords(30));
        p1.setShortContent(loremIpsum.getWords(10));
        p1.setDescription("Topeni pro mazdu a volvo");
        p1.setEnabled(true);
        p1.setName("Topeni pro mazdu a volvo");
        p1.setPrice(BigDecimal.valueOf(12));
        p1.setCarType("mazda;volvo");

        Product p2 = new Product();
        p2.setContent(loremIpsum.getWords(30));
        p2.setShortContent(loremIpsum.getWords(10));
        p2.setDescription("Topeni pro mazdu");
        p2.setEnabled(true);
        p2.setName("Topeni pro mazdu");
        p2.setPrice(BigDecimal.valueOf(12));
        p2.setCarType("mazda");

        Product p3 = new Product();
        p3.setDescription("Topeni pro porshe");
        p3.setContent(loremIpsum.getWords(30));
        p3.setShortContent(loremIpsum.getWords(10));
        p3.setEnabled(true);
        p3.setName("Topeni pro porshe");
        p3.setPrice(BigDecimal.valueOf(12));
        p3.setCarType("porshe");

        Product p4 = new Product();
        p4.setDescription("Komponenta pro topeni pro mazdu a volvo");
        p4.setContent(loremIpsum.getWords(30));
        p4.setShortContent(loremIpsum.getWords(10));
        p4.setEnabled(true);
        p4.setName("Komponenta 1 pro topeni pro mazdu a volvo");
        p4.setPrice(BigDecimal.valueOf(12));

        Product p5 = new Product();
        p5.setDescription("Komponenta 2 pro topeni pro mazdu a volvo");
        p5.setContent(loremIpsum.getWords(30));
        p5.setShortContent(loremIpsum.getWords(10));
        p5.setEnabled(true);
        p5.setName("Komponenta 1 pro topeni pro mazdu a volvo");
        p5.setPrice(BigDecimal.valueOf(12));


        productRepository.save(p1);
        productRepository.save(p2);
        productRepository.save(p3);
        productRepository.save(p4);
        productRepository.save(p5);
        shopAdminService.addProductToCategory(p2, c1);
        shopAdminService.addProductToCategory(p3, c1);
        shopAdminService.addProductToCategory(p2, c2);
        shopAdminService.addProductToCategory(p1, c3);
        shopAdminService.addProductToCategory(p4, c4);
        shopAdminService.addProductToCategory(p5, c4);


        Set<Long> list = new HashSet<Long>();
        list.add(p4.getId());
        list.add(p5.getId());
        shopAdminService.setComponentsOfProduct(p1.getId(), list);
        shopAdminService.setRelatedProducts(p1.getId(), list);


//       productRepository.save(p1);
//       
//       p1.addRelatedProduct(p2);
//       p2.addRelatedProduct(p1);
        productRepository.save(p1);
//       p1.addRelatedProduct(p3);
//       p3.addRelatedProduct(p1);
//
//           productRepository.save(p2);
//        productRepository.save(p3);


    }

    private void setUpCategories(Category c1, Category c2, Category c3, Category c4, Category c5) {
        c1.setTitle("topeni1");
        c1.setContent(loremIpsum.getWords(30));
        c1.setDescription("topeni1");
        c1.setKeywords("topeni1");
        c1.setParent(null);

        c2.setTitle("topeni2");
        c2.setContent(loremIpsum.getWords(30));
        c2.setDescription("topeni2");
        c2.setKeywords("topeni2");
        c2.setParent(null);

        c3.setParent(c1);
        c3.setTitle("topeni1-1");
        c3.setContent(loremIpsum.getWords(30));
        c3.setDescription("topeni1-1");
        c3.setKeywords("topeni1-1");

        c4.setParent(c1);
        c4.setTitle("topeni1-2");
        c4.setContent(loremIpsum.getWords(30));
        c4.setDescription("topeni1-2");
        c4.setKeywords("topeni1-2");

        c5.setParent(c2);
        c5.setTitle("topeni2-1");
        c5.setContent(loremIpsum.getWords(30));
        c5.setDescription("topeni2-1");
        c5.setKeywords("topeni2-1");

        List<Category> list1 = new ArrayList<Category>();
        list1.add(c3);
        list1.add(c4);
        list1.add(c5);
        c1.setChilds(list1);

        List<Category> list2 = new ArrayList<Category>();
        list2.add(c5);
        c2.setChilds(list2);
    }

    private void createCategoriesAndProducts() throws Exception {
        Category c1 = new Category();
        Category c2 = new Category();
        Category c3 = new Category();
        Category c4 = new Category();
        Category c5 = new Category();
        categoryRepository.save(c1);
        categoryRepository.save(c2);
        categoryRepository.save(c3);
        categoryRepository.save(c4);
        categoryRepository.save(c5);
        setUpCategories(c1, c2, c3, c4, c5);
        createProducts(c1, c2, c3, c4, c5);

    }

    private void createUsers() throws Exception {
        admin = new User();
        admin.setAdmin(true);
        admin.setEnabled(true);
        admin.setLogin("admin");
        admin.setCompanyEmail("vojta.krasa@gmail.com");
        admin.setPassword("admin");
        userRepository.save(admin);

        User u1 = new User();
        u1.setAdmin(true);

        u1.setBankNumber("0800-" + randomInt(100000000, 999000000));
        u1.setCompanyEmail("vojta.krasa@gmail.com");
        u1.setCompanyID(randomInt(100000000, 999000000).toString());
        u1.setCountry("CZ");
        u1.setEnabled(true);
        u1.setFax("+420 274 817 434");
        u1.setFirstName("Jan");
        u1.setLastName("vojta");
        u1.setLogin("vojta");
        u1.setMunicipality("Praha");
        u1.setPassword("vojta");
        u1.setPhone("+420 274 773 023");
        u1.setPostcode("415 01");
        u1.setStreet("PodÄ›bradskĂˇ");
        u1.setTaxID("CZ6005133123");
        u1.setTradingName("Comesa spol. s r.o.");
        u1.setTradingName2("Otec a syn");

        User u2 = new User();
        u2.setAdmin(false);
        u2.setBankNumber("0400-" + randomInt(100000000, 999000000));
        u2.setCompanyEmail("prodej@obchodnici.cz");
        u2.setCompanyID(randomInt(100000000, 999000000).toString());
        u2.setCountry("CZ");
        u2.setEnabled(true);
        u2.setFax("+420 456 666 777");
        u2.setFirstName("Petr");
        u2.setLastName("Kolben");
        u2.setLogin("kolben");
        u2.setMunicipality("Praha");
        u2.setPassword("123");
        u2.setPhone("+420 274 666 023");
        u2.setPostcode("156 01");
        u2.setStreet("Kolbenova");
        u2.setTaxID("CZ6007773123");
        u2.setTradingName("ENDOIMPLANT spol. s r.o.");
        u2.setTradingName2("");

        User u3 = new User();
        u3.setAdmin(false);
        u3.setBankNumber("0500-" + randomInt(100000000, 999000000));
        u3.setCompanyEmail("deathfi@seznam.cz");
        u3.setCompanyID(randomInt(100000000, 999000000).toString());
        u3.setCountry("CZ");
        u3.setEnabled(true);
        u3.setFax("+420 461 817 434");
        u3.setFirstName("Pavel");
        u3.setLastName("Svoboda");
        u3.setLogin("svoboda");
        u3.setMunicipality("Praha");
        u3.setPassword("123");
        u3.setPhone("+420 274 333 023");
        u3.setPostcode("333 01");
        u3.setStreet("MlĂ©kĂˇrenskĂˇ");
        u3.setTaxID("CZ6001113123");
        u3.setTradingName("Lima CZ s.r.o.");
        u3.setTradingName2("");

        userRepository.save(u1);
        userRepository.save(u2);
        userRepository.save(u3);
    }

    private void createDeliveryMethods() throws Exception {
        DeliveryMethod dm = new DeliveryMethod();
        dm.setName("PPL");
        dm.setPrice(BigDecimal.valueOf(12));
        dm.setContent("Nejlepsi pro nase zakazniky");

        DeliveryMethod dm2 = new DeliveryMethod();
        dm2.setName("PoĹˇta");
        dm2.setPrice(BigDecimal.valueOf(12));
        dm2.setContent("Nejlevnejsi, ale pomala");

        DeliveryMethod dm3 = new DeliveryMethod();
        dm3.setName("DLL");
        dm3.setContent("Luxusni");
        dm3.setPrice(BigDecimal.valueOf(12));

        deliveryMethodRepository.save(dm);
        deliveryMethodRepository.save(dm2);
        deliveryMethodRepository.save(dm3);
    }

    private void createPayMethods() throws Exception {
        PayMethod pm2 = new PayMethod();
        pm2.setName("sek");
        pm2.setContent("Klasika");

        PayMethod pm3 = new PayMethod();
        pm3.setName("dobirka");
        pm3.setContent("Jen v krajnim pripade.");

        PayMethod pm4 = new PayMethod();
        pm4.setName("na miste");
        pm4.setContent("Nejlepsi pro nas");

        payMethodRepository.save(pm2);
        payMethodRepository.save(pm3);
        payMethodRepository.save(pm4);
    }

    private void addNewCategory(CmsPage cmsPage) {
        CmsPage category = new CmsPage(admin);
        category.setTitle(randomString(4, 10));
        category.setContent(loremIpsum.getParagraphs(randomInt(1, 10)));


        CmsPage cmsPage1 = new CmsPage(admin);
        cmsPage1.setTitle(randomString(4, 10));
        cmsPage1.setContent(loremIpsum.getParagraphs(randomInt(1, 10)));

        CmsPage cmsPage12 = new CmsPage(admin);
        cmsPage12.setTitle(randomString(4, 10));
        cmsPage12.setContent(loremIpsum.getParagraphs(randomInt(1, 10)));


        category.getChilds().add(cmsPage1);
        cmsPage1.setParent(category);
        category.getChilds().add(cmsPage12);
        cmsPage12.setParent(category);
        cmsPage.getChilds().add(category);
        category.setParent(cmsPage);

    }

    private void makeSection() throws Exception {
        CmsPage cmsPage = new CmsPage(admin);
        cmsPage.setTitle(randomString(4, 10));
        cmsPage.setContent(loremIpsum.getParagraphs(randomInt(1, 10)));
        addNewCategory(cmsPage);
        addNewCategory(cmsPage);
        addNewCategory(cmsPage);


        cmsPageRepository.save(cmsPage);
    }

    private static Integer randomInt(int min, int max) {
        return (int) (Math.random() * (max - min) + min);
    }

    private static String randomString(int min, int max) {
        int num = randomInt(min, max);
        byte b[] = new byte[num];
        for (int i = 0; i < num; i++) {
            b[i] = (byte) randomInt('a', 'z').intValue();
        }
        return new String(b);
    }

    public void setCmsAdminService(CmsAdminService cmsAdminService) {
        this.cmsAdminService = cmsAdminService;
    }

    public void setConfigurationRepository(ConfigurationRepository configurationRepository) {
        this.configurationRepository = configurationRepository;
    }

    public void setCategoryRepository(CategoryRepository categoryRepository) {
        this.categoryRepository = categoryRepository;
    }

    public void setProductRepository(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public void setDeliveryMethodRepository(DeliveryMethodRepository deliveryMethodRepository) {
        this.deliveryMethodRepository = deliveryMethodRepository;
    }

    public void setPayMethodRepository(PayMethodRepository payMethodRepository) {
        this.payMethodRepository = payMethodRepository;
    }

    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }


    public void setLoremIpsum(LoremIpsum loremIpsum) {
        this.loremIpsum = loremIpsum;
    }

    public void setCmsPageRepository(CmsPageRepository cmsPageRepository) {
        this.cmsPageRepository = cmsPageRepository;
    }


}


